package com.zhs.gccs.view.taskMap;

import android.content.Context;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.amap.api.maps.AMapUtils;
import com.amap.api.maps.model.LatLng;
import com.amap.api.navi.AMapNavi;
import com.amap.api.navi.AMapNaviListener;
import com.amap.api.navi.AMapNaviView;
import com.amap.api.navi.AMapNaviViewListener;
import com.amap.api.navi.AMapNaviViewOptions;
import com.amap.api.navi.ParallelRoadListener;
import com.amap.api.navi.enums.AMapNaviParallelRoadStatus;
import com.amap.api.navi.enums.NaviType;
import com.amap.api.navi.model.AMapCalcRouteResult;
import com.amap.api.navi.model.AMapLaneInfo;
import com.amap.api.navi.model.AMapModelCross;
import com.amap.api.navi.model.AMapNaviCameraInfo;
import com.amap.api.navi.model.AMapNaviCross;
//import com.amap.api.navi.model.AMapNaviInfo;
import com.amap.api.navi.model.AMapNaviLocation;
import com.amap.api.navi.model.AMapNaviRouteNotifyData;
import com.amap.api.navi.model.AMapNaviTrafficFacilityInfo;
import com.amap.api.navi.model.AMapServiceAreaInfo;
import com.amap.api.navi.model.AimLessModeCongestionInfo;
import com.amap.api.navi.model.AimLessModeStat;
import com.amap.api.navi.model.NaviInfo;
import com.amap.api.navi.model.NaviLatLng;
//import com.autonavi.tbt.TrafficFacilityInfo;
import com.mapbox.geojson.Point;
import com.zhs.gccs.R;
import com.zhs.gccs.model.LocationBean;
import com.zhs.gccs.utils.GPSUtils;
import com.zhs.gccs.utils.ZuobiaoTransforlation;
import com.zhs.gccs.view.BaseView;

import java.util.ArrayList;
import java.util.List;

public class GdNavView extends BaseView implements AMapNaviViewListener, AMapNaviListener, ParallelRoadListener {

    public static interface GdNarListener{
        void onNavLocationChange(int zoom,AMapNaviLocation location);
        void onNavEnd();

        void onCalculateRouteSuccess(List<Point> points);
    }
    private GdNarListener gdNarListener;

    public void setGdNarListener(GdNarListener gdNarListener) {
        this.gdNarListener = gdNarListener;
    }

    private boolean isDriving = false;

    private AMapNaviView naviView;
    private TextView tv_start;
    private TextView tv_end;
    protected AMapNavi mAMapNavi;
//    private OverviewButtonView overviewButtonView;
    protected final List<NaviLatLng> sList = new ArrayList<NaviLatLng>();
    protected final List<NaviLatLng> eList = new ArrayList<NaviLatLng>();
    protected List<NaviLatLng> mWayPointList = new ArrayList<NaviLatLng>();

    public GdNavView(@NonNull Context context) {
        super(context);
    }

    public GdNavView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public GdNavView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void init(Context context, AttributeSet attrs, int defStyleAttr) {
        this.context = context;
        View view = LayoutInflater.from(context).inflate(R.layout.layout_nav_gd, this, true);
        naviView = view.findViewById(R.id.naviView);
        tv_start = view.findViewById(R.id.tv_start);
        tv_end = view.findViewById(R.id.tv_end);
//        overviewButtonView = view.findViewById(R.id.overviewButtonView);
    }

    public final void onCreate(Bundle bundle) {
        naviView.onCreate(bundle);
        try {
            mAMapNavi = AMapNavi.getInstance(context);
            mAMapNavi.addAMapNaviListener(this);
            mAMapNavi.addParallelRoadListener(this);
            mAMapNavi.setUseInnerVoice(true, true);
            //设置模拟导航的行车速度
            mAMapNavi.setEmulatorNaviSpeed(75);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //设置布局完全不可见
        AMapNaviViewOptions options = naviView.getViewOptions();
//        RouteOverlayOptions routeOverlayOptions = new RouteOverlayOptions();
//        routeOverlayOptions.setArrowOnTrafficRoute(BitmapFactory.decodeResource(getResources(),
//                R.drawable.custtexture_aolr));
//        routeOverlayOptions.setNormalRoute(BitmapFactory.decodeResource(getResources(),
//                R.drawable.custtexture));
//        routeOverlayOptions.setUnknownTraffic(BitmapFactory.decodeResource(getResources(),
//                R.drawable.custtexture_no));
//        routeOverlayOptions.setSmoothTraffic(BitmapFactory.decodeResource(getResources(),
//                R.drawable.custtexture_green));
//        routeOverlayOptions.setSlowTraffic(BitmapFactory.decodeResource(getResources(),
//                R.drawable.custtexture_slow));
//        routeOverlayOptions.setJamTraffic(BitmapFactory.decodeResource(getResources(),
//                R.drawable.custtexture_bad));
//        routeOverlayOptions.setVeryJamTraffic(BitmapFactory.decodeResource(getResources(),
//                R.drawable.custtexture_grayred));
//        options.setRouteOverlayOptions(routeOverlayOptions);
//        options.setLayoutVisible(false);
        options.setCarBitmap(BitmapFactory.decodeResource(this.getResources(), R.mipmap.customcar));
        options.setFourCornersBitmap(BitmapFactory.decodeResource(this.getResources(), R.mipmap.navi_direction));
        options.setStartPointBitmap(BitmapFactory.decodeResource(this.getResources(), R.mipmap.navi_start));
        options.setWayPointBitmap(BitmapFactory.decodeResource(this.getResources(), R.mipmap.navi_way));
        options.setEndPointBitmap(BitmapFactory.decodeResource(this.getResources(), R.mipmap.navi_end));
        naviView.setViewOptions(options);
//        naviView.setLazyOverviewButtonView(overviewButtonView);
        naviView.setAMapNaviViewListener(this);
        naviView.setNaviMode(AMapNaviView.CAR_UP_MODE);
    }

    public void startNar(LocationBean start, LocationBean end) {
        sList.clear();
        eList.clear();
        mWayPointList.clear();
        tv_start.setText(start.getAddress());
        tv_end.setText(end.getAddress());
        Point point = ZuobiaoTransforlation.newInstance().wgs84togcj02(start.getLon(), start.getLat());
        sList.add(new NaviLatLng(point.latitude(),point.longitude()));
        Point point2 = ZuobiaoTransforlation.newInstance().wgs84togcj02(end.getLon(), end.getLat());
        eList.add(new NaviLatLng(point2.latitude(),point2.longitude()));
        initCalcNav();
    }

    private void initCalcNav() {
        /**
         * 方法: int strategy=mAMapNavi.strategyConvert
         * (congestion, avoidhightspeed, cost, hightspeed, multipleroute);
         * 参数:
         * @congestion 躲避拥堵
         * @avoidhightspeed 不走高速
         * @cost 避免收费
         * @hightspeed 高速优先
         * @multipleroute 多路径
         *  说明: 以上参数都是boolean类型，其中multipleroute参数表示是否多条路线，如果为true则此策略会算出多条路线。
         *  注意: 不走高速与高速优先不能同时为true 高速优先与避免收费不能同时为true
         */
        int strategy = 0;
        try {
            //再次强调，最后一个参数为true时代表多路径，否则代表单路径
            strategy = mAMapNavi.strategyConvert(true,
                    false,
                    false,
                    false,
                    false);
        } catch (Exception e) {
            e.printStackTrace();
        }
        mAMapNavi.calculateDriveRoute(sList, eList, mWayPointList, strategy);
    }


    private void toStart(){
        mAMapNavi.startNavi(NaviType.GPS);//NaviType.EMULATOR模拟器    NaviType.GPS
    }

    public void onResume() {
        naviView.onResume();
    }

    public void onPause() {
        naviView.onPause();
//        停止导航之后，会触及底层stop，然后就不会再有回调了，但是讯飞当前还是没有说完的半句话还是会说完
//        mAMapNavi.stopNavi();
    }

    public void onDestroy(){
        naviView.onDestroy();
        //since 1.6.0 不再在naviview destroy的时候自动执行AMapNavi.stopNavi();请自行执行
        if (mAMapNavi!=null){
            mAMapNavi.stopNavi();
            mAMapNavi.destroy();
        }
    }

    @Override
    public void onInitNaviSuccess() {
        //初始化成功
    }
    @Override
    public void onInitNaviFailure() {
        Toast.makeText(context, "init navi Failed", Toast.LENGTH_SHORT).show();
        isDriving = false;
    }



    @Override
    public void onStartNavi(int type) {
        //开始导航回调
        Log.i("导航","开始导航");
        isDriving = true;
    }

    @Override
    public void onTrafficStatusUpdate() {
        //
    }

    private AMapNaviLocation preLocation;
    @Override
    public void onLocationChange(AMapNaviLocation location) {
        if(!isDriving)return;
        double distance = 0;
        if(preLocation!=null){
            distance = AMapUtils.calculateLineDistance(
                    new LatLng(preLocation.getCoord().getLatitude(),preLocation.getCoord().getLongitude()),
                    new LatLng(location.getCoord().getLatitude(),location.getCoord().getLongitude()));
        }
        //当前位置回调h
         if(gdNarListener!=null&&(preLocation==null||distance>10)){
             int lockZoom = naviView.getLockZoom();
             gdNarListener.onNavLocationChange(lockZoom,location);
             preLocation = location;
         }
    }

    @Override
    public void onNaviCancel() {
        //取消导航
        isDriving = false;
        if(gdNarListener!=null)gdNarListener.onNavEnd();
    }

    @Override
    public void onGetNavigationText(int type, String text) {
        //播报类型和播报文字回调
    }

    @Override
    public void onGetNavigationText(String s) {

    }

    @Override
    public void onEndEmulatorNavi() {
        //结束模拟导航
        isDriving = false;
        if(gdNarListener!=null)gdNarListener.onNavEnd();
    }

    @Override
    public void onArriveDestination() {
        //到达目的地
        isDriving = false;
        if(gdNarListener!=null)gdNarListener.onNavEnd();
    }

    @Override
    public void onCalculateRouteFailure(int errorInfo) {
        isDriving = false;
    }

    @Override
    public void onReCalculateRouteForYaw() {
        //偏航后重新计算路线回调
    }

    @Override
    public void onReCalculateRouteForTrafficJam() {
        //拥堵后重新计算路线回调
    }
    @Override
    public void onCalculateRouteSuccess(int[] ints) {
        //多路径算路成功回调
    }

    @Override
    public void onCalculateRouteSuccess(AMapCalcRouteResult aMapCalcRouteResult) {
        toStart();
        //主路线概览
        List<Point> points = new ArrayList<>();
//        Stream.of(sList).forEach(item->{
//            double[] lnglat = GPSUtils.gcj02towgs84(item.getLongitude(), item.getLatitude());
//            points.add(Point.fromLngLat(lnglat[0],lnglat[1]));
//        });
//        Stream.of(eList).forEach(item->{
//            double[] lnglat = GPSUtils.gcj02towgs84(item.getLongitude(), item.getLatitude());
//            points.add(Point.fromLngLat(lnglat[0],lnglat[1]));
//        });
//        List<AMapNaviRouteGuideGroup> guideList = mAMapNavi.getNaviPath().getNaviGuideList();
        List<NaviLatLng> wayPoint = mAMapNavi.getNaviPath().getCoordList();
        for (int i = 0; i < wayPoint.size(); i++) {
//            AMapNaviRouteGuideGroup guide = guideList.get(i);
            NaviLatLng guide = wayPoint.get(i);
            double[] lnglat = GPSUtils.gcj02towgs84(guide.getLongitude(), guide.getLatitude());
            points.add(Point.fromLngLat(lnglat[0],lnglat[1]));
            //guide step相生相惜，指的是大导航段
//            AMapNaviRouteGuideGroup guide = guideList.get(i);
//            Log.d("wlx", "AMapNaviRouteGuideGroup 路线名:" + guide.getGroupName() + "");
//            Log.d("wlx", "AMapNaviRouteGuideGroup 路线长:" + guide.getGroupLen() + "m");
//            Log.d("wlx", "AMapNaviRouteGuideGroup 路线IconType" + guide.getGroupIconType() + "");
//            Log.d("wlx", "AMapNaviRouteGuideGroup 红绿灯数量" + guide.getTrafficLightsCount() + "");
        }
        if(gdNarListener!=null)gdNarListener.onCalculateRouteSuccess(points);
    }

    @Override
    public void onCalculateRouteFailure(AMapCalcRouteResult result) {
        isDriving = false;
        //路线计算失败
        Log.e("dm", "--------------------------------------------");
        Log.i("dm", "路线计算失败：错误码=" + result.getErrorCode() + ",Error Message= " +
                result.getErrorCode());
        Log.i("dm", "错误码详细链接见：http://lbs.amap.com/api/android-navi-sdk/guide/tools/errorcode/");
        Log.e("dm", "--------------------------------------------");
//        Toast.makeText(context, "errorInfo：" + result.getErrorDetail() + ", Message：" + result.getErrorDetail(), Toast.LENGTH_LONG).show();
    }

    @Override
    public void onArrivedWayPoint(int wayID) {
        //到达途径点
    }

    @Override
    public void onGpsOpenStatus(boolean enabled) {
        //GPS开关状态回调
    }

    @Override
    public void onNaviSetting() {
        //底部导航设置点击回调
    }

    @Override
    public void onNaviMapMode(int naviMode) {
        //导航态车头模式，0:车头朝上状态；1:正北朝上模式。
    }




    @Override
    public void onNaviTurnClick() {
        //转弯view的点击回调
    }

    @Override
    public void onNextRoadClick() {
        //下一个道路View点击回调
    }


    @Override
    public void onScanViewButtonClick() {
        //全览按钮点击回调
    }

    @Override
    public void updateCameraInfo(AMapNaviCameraInfo[] aMapCameraInfos) {

    }
    @Override
    public void updateIntervalCameraInfo(AMapNaviCameraInfo aMapNaviCameraInfo,
                                         AMapNaviCameraInfo aMapNaviCameraInfo1, int i) {

    }

    @Override
    public void onServiceAreaUpdate(AMapServiceAreaInfo[] amapServiceAreaInfos) {

    }

    @Override
    public void onNaviInfoUpdate(NaviInfo naviinfo) {
        //导航过程中的信息更新，请看NaviInfo的具体说明
    }



    @Override
    public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo aMapNaviTrafficFacilityInfo) {
        //已过时
    }



    @Override
    public void showCross(AMapNaviCross aMapNaviCross) {
        //显示放大图回调
    }

    @Override
    public void hideCross() {
        //隐藏放大图回调
    }

    @Override
    public void showLaneInfo(AMapLaneInfo[] laneInfos, byte[] laneBackgroundInfo, byte[] laneRecommendedInfo) {
        //显示车道信息

    }

    @Override
    public void hideLaneInfo() {
        //隐藏车道信息
    }



    @Override
    public void notifyParallelRoad(int i) {
    }

    @Override
    public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos) {
        //更新交通设施信息
    }

    @Override
    public void updateAimlessModeStatistics(AimLessModeStat aimLessModeStat) {
        //更新巡航模式的统计信息
    }


    @Override
    public void updateAimlessModeCongestionInfo(AimLessModeCongestionInfo aimLessModeCongestionInfo) {
        //更新巡航模式的拥堵信息
    }

    @Override
    public void onPlayRing(int i) {

    }


    @Override
    public void onLockMap(boolean isLock) {
        //锁地图状态发生变化时回调
    }

    @Override
    public void onNaviViewLoaded() {
        Log.d("wlx", "导航页面加载成功");
        Log.d("wlx", "请不要使用AMapNaviView.getMap().setOnMapLoadedListener();会overwrite导航SDK内部画线逻辑");
    }

    @Override
    public void onMapTypeChanged(int i) {

    }

    @Override
    public void onNaviViewShowMode(int i) {

    }

    @Override
    public boolean onNaviBackClick() {
        return false;
    }


    @Override
    public void showModeCross(AMapModelCross aMapModelCross) {
    }

    @Override
    public void hideModeCross() {

    }



    @Override
    public void showLaneInfo(AMapLaneInfo aMapLaneInfo) {

    }



    @Override
    public void onNaviRouteNotify(AMapNaviRouteNotifyData aMapNaviRouteNotifyData) {

    }

    @Override
    public void onGpsSignalWeak(boolean b) {

    }


    @Override
    public void notifyParallelRoad(AMapNaviParallelRoadStatus aMapNaviParallelRoadStatus) {
        if (aMapNaviParallelRoadStatus.getmElevatedRoadStatusFlag() == 1) {
            Toast.makeText(context, "当前在高架上", Toast.LENGTH_SHORT).show();
            Log.d("wlx", "当前在高架上");
        } else if (aMapNaviParallelRoadStatus.getmElevatedRoadStatusFlag() == 2) {
            Toast.makeText(context, "当前在高架下", Toast.LENGTH_SHORT).show();
            Log.d("wlx", "当前在高架下");
        }

        if (aMapNaviParallelRoadStatus.getmParallelRoadStatusFlag() == 1) {
            Toast.makeText(context, "当前在主路", Toast.LENGTH_SHORT).show();
            Log.d("wlx", "当前在主路");
        } else if (aMapNaviParallelRoadStatus.getmParallelRoadStatusFlag() == 2) {
            Toast.makeText(context, "当前在辅路", Toast.LENGTH_SHORT).show();
            Log.d("wlx", "当前在辅路");
        }
    }
}
